/*
 * handleUpload function
 * Info:
 * This function is used to handle incoming upload requests.
 * e.g. a user wants to upload a file to the server.
 * the amount of bytes that should be written also have to be known
 * to check if the upload is complete or not.
 */

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h> //memory map files dingen
#include <semaphore.h>
#include <unistd.h>
#include <string.h>

#define UPMAPFILE "/tmp/mmappedupload.bin" //map file for uploads
#define FILESIZE (sizeof(UPMAPFILE) * sizeof(int))
#define MSGERRFILE "ERROR"

int handleUpload(char *pathname, char *filename, int comChannelfd)
{
    char *upMap; //upload mmap (read only)
    int filefd = 0; //file descriptor for the file that has to be written
    int upfd = 0;
    sem_t *semUpFull;
    sem_t *semUpEmpty;
    sem_t *semComChanRead;
    sem_t *semComChanPost;

    //semaphore stuff for uploads
    //sem_unlink("semUpFull");
    if((semUpFull = sem_open("semUpFull", 0))== SEM_FAILED)
    {
        perror("semopen semUpFull: ");
    }
    //sem_unlink("semUpEmpty");
    if((semUpEmpty = sem_open("semUpEmpty", 0))== SEM_FAILED)
    {
        perror("semopen semUpEmpty: ");
    }
    if((semComChanPost = sem_open("semComChanPost", 0))== SEM_FAILED)
    {
        perror("semopen semComChanPost: ");
    }
    if((semComChanRead = sem_open("semComChanRead", 0))== SEM_FAILED)
    {
        perror("semopen semComChanPost: ");
    }
    //end of semaphore stuff

    //create file on disk, if it exists, error (or overwrite, not sure which one yet)
    if((filefd = open(filename, O_CREAT | O_RDWR, 0600))<0)
    {
        perror("can't create file:");
        write(comChannelfd, MSGERRFILE, strlen(MSGERRFILE));
        return 0;
    }
    //end of file creation

    //notify CHP
    write(comChannelfd, "READY\0", 6);
    printf("comchannelfd: %d\n", comChannelfd);
    sem_post(semComChanRead);
    sem_post(semUpEmpty);
    //

    //while loop for writing file to disk
    while(strcmp(upMap, "\0")) //we still have to determine what the message is for when we are done with a file
    {
        sem_wait(semUpFull);
        //open the upload memory map file
        upfd = open(UPMAPFILE, O_RDONLY);
        if(upfd < 0)
        {
            perror("Could not open the upload file for reading!");
            exit(EXIT_FAILURE);
        }
        //end of opening upload memory map file

        //memory map the shared file
        upMap = mmap(0, FILESIZE, PROT_READ, MAP_SHARED, upfd, 0);
        if (upMap == MAP_FAILED)
        {
            close(upfd);
            perror("Error memory mapping the file");
            exit(EXIT_FAILURE);
        }
        //end of memory mapping

        //!!!!!debug line to check upMap content!!!!!
        printf("upMap: %s\n", upMap);
        //!!!!! end of debug line!!!!!
        printf("filefd: %d\n", filefd);
        printf("going to write\n");
        if((write(filefd, upMap, strlen(upMap))<0))
        {
            perror("write");
        }
        printf("written\n");
        sem_post(semUpEmpty);
        //break;
    }
    //end of loop
close(upfd);
printf("closed upfd\n");
return 0;
}
//end of handleUpload